package com.jms.framework.beans.factory;

import com.jms.framework.aop.management.AopManagementAdapter;
import com.jms.framework.aware.ApplicationContextAware;
import com.jms.framework.beans.BeanDefinition;
import com.jms.framework.jdbc.transaction.adaper.TransactionManagementAdapter;
import com.jms.framework.jdbc.transaction.proxy.TransactionProxyFactory;
import com.jms.framework.beans.utils.BeanInitializeUtils;
import com.jms.framework.jdbc.transaction.utils.TransactionUtils;

/**
 * 实现了ObjectFactory接口的BeanDefinitionObjectFactory类
 * 用于根据BeanDefinition创建对象实例
 * @author JMS
 * @since 20250123
 * @version 1.0.0
 *
 * @param <T> 泛型参数，表示将要创建的对象类型
 */
public class GeneralBeanFactory<T> extends AbstractBeanFactory<T> {

    /**
     * 构造方法，初始化BeanDefinitionObjectFactory实例
     *
     * @param beanDefinition Bean定义，包含创建对象所需的信息
     */
    public GeneralBeanFactory(BeanDefinition beanDefinition) {
        super(beanDefinition);
    }

    /**
     * 根据bean定义获取对象实例
     * 此方法负责根据bean定义中的类名创建对象实例，并进行一些初始化操作
     * 如果bean类实现了特定的Aware接口，还会进行相应的初始化处理
     *
     * @return T 返回创建的对象实例，如果无法创建则返回null
     * @throws Exception 如果对象创建过程中发生错误则抛出异常
     */
    @Override
    @SuppressWarnings("unchecked")
    public T getObject() throws Exception {
        // 获取bean定义中的类名
        String beanClassName = beanDefinition.getBeanClassName();
        // 如果类名为空，则返回null
        if (beanClassName == null) {
            return null;
        }

        // 通过类名加载类
        Class<?> beanClass = Class.forName(beanClassName);
        // 创建对象实例
        Object bean = beanClass.newInstance();
        //创建事务代理
        if (TransactionUtils.haveTransaction(beanClass) && TransactionManagementAdapter.transactionManagementIsOpen()) {
            bean = TransactionProxyFactory.getCglibProxy(bean);
        }
        // 创建Aop代理
        if (AopManagementAdapter.aopManagementIsOpen()) {
            bean = AopManagementAdapter.getInstance().createAopProxy(bean);
        }
        // 检查并处理bean是否实现了ApplicationContextAware接口
        if (BeanInitializeUtils.isAware(beanClass)) {
            BeanInitializeUtils.initAware((ApplicationContextAware) bean);
        }

        // 将对象强制转换为泛型类型T并返回
        return (T) bean;
    }
}
